package com.fattyCorps.battle.service.battle.behavior;

import com.fattyCorps.battle.service.battle.Battle;
import com.fattyCorps.battle.service.battle.data.BattleData;
import com.fattyCorps.battle.service.battle.data.BattleHero;
import com.fattyCorps.common.enums.battle.ESkillTargetType;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

public class TargetSelector {

    public static List<BattleHero> select(Battle battle, BattleHero srcHero, ESkillTargetType targetType) {
        BattleData battleData = battle.getBattleData();
        List<BattleHero> retList = new ArrayList<>();

        if (targetType.equals(ESkillTargetType.EnemyAll)) {
            retList.addAll(filterDead(battleData.getEnemy(srcHero).getHeroes()));
        } else if (targetType.equals(ESkillTargetType.FirstEnemy)) {
            retList.add(battleData.getEnemy(srcHero).getFirst());
        } else if (targetType.equals(ESkillTargetType.EnemyFront)) {
            retList.addAll(battleData.getEnemy(srcHero).getFront());
        } else if (targetType.equals(ESkillTargetType.EnemyBack)) {
            retList.addAll(battleData.getEnemy(srcHero).getBack());
        } else if (targetType.equals(ESkillTargetType.EnemyRand1)) {
            retList.addAll(randHeroes(filterDead(battleData.getEnemy(srcHero).getHeroes()), 1));
        } else if (targetType.equals(ESkillTargetType.EnemyRand2)) {
            retList.addAll(randHeroes(filterDead(battleData.getEnemy(srcHero).getHeroes()), 2));
        } else if (targetType.equals(ESkillTargetType.EnemyRand3)) {
            retList.addAll(randHeroes(filterDead(battleData.getEnemy(srcHero).getHeroes()), 3));
        } else if (targetType.equals(ESkillTargetType.EnemyRand4)) {
            retList.addAll(randHeroes(filterDead(battleData.getEnemy(srcHero).getHeroes()), 4));
        } else if (targetType.equals(ESkillTargetType.EnemyRand5)) {
            retList.addAll(randHeroes(filterDead(battleData.getEnemy(srcHero).getHeroes()), 5));
        } else if (targetType.equals(ESkillTargetType.Self)) {
            retList.add(srcHero);
        } else if (targetType.equals(ESkillTargetType.PartnerFront)) {
            retList.addAll(battleData.getPartner(srcHero).getFront());
        } else if (targetType.equals(ESkillTargetType.PartnerBack)) {
            retList.addAll(battleData.getPartner(srcHero).getBack());
        } else if (targetType.equals(ESkillTargetType.PartnerAll)) {
            retList.addAll(filterDead(battleData.getPartner(srcHero).getHeroes()));
        } else if (targetType.equals(ESkillTargetType.PartnerRand1)) {
            retList.addAll(randHeroes(filterDead(battleData.getPartner(srcHero).getHeroes()), 1));
        } else if (targetType.equals(ESkillTargetType.PartnerRand2)) {
            retList.addAll(randHeroes(filterDead(battleData.getPartner(srcHero).getHeroes()), 2));
        } else if (targetType.equals(ESkillTargetType.PartnerRand3)) {
            retList.addAll(randHeroes(filterDead(battleData.getPartner(srcHero).getHeroes()), 3));
        } else if (targetType.equals(ESkillTargetType.PartnerRand4)) {
            retList.addAll(randHeroes(filterDead(battleData.getPartner(srcHero).getHeroes()), 4));
        } else if (targetType.equals(ESkillTargetType.PartnerRand5)) {
            retList.addAll(randHeroes(filterDead(battleData.getPartner(srcHero).getHeroes()), 5));
        } else if (targetType.equals(ESkillTargetType.EnemyHighestAtt)) {
            BattleHero targetHero = null;
            List<BattleHero> heroes = filterDead(battleData.getEnemy(srcHero).getHeroes());
            for (BattleHero hero : heroes) {
                if (targetHero == null) {
                    targetHero = hero;
                } else {
                    if (Integer.valueOf(hero.getHero().getPropComp().getAtt()) > Integer.valueOf(targetHero.getHero().getPropComp().getAtt())) {
                        targetHero = hero;
                    }
                }
            }

            retList.add(targetHero);
        } else if (targetType.equals(ESkillTargetType.EnemyHighestHp)) {
            BattleHero targetHero = null;
            List<BattleHero> heroes = filterDead(battleData.getEnemy(srcHero).getHeroes());
            for (BattleHero hero : heroes) {
                if (targetHero == null) {
                    targetHero = hero;
                } else {
                    if (hero.getHp() > targetHero.getHp()) {
                        targetHero = hero;
                    }
                }
            }

            retList.add(targetHero);
        } else if (targetType.equals(ESkillTargetType.EnemyHighestMaxHp)) {
            BattleHero targetHero = null;
            List<BattleHero> heroes = filterDead(battleData.getEnemy(srcHero).getHeroes());
            for (BattleHero hero : heroes) {
                if (targetHero == null) {
                    targetHero = hero;
                } else {
                    if (Integer.valueOf(hero.getHero().getPropComp().getMaxHp()) > Integer.valueOf(targetHero.getHero().getPropComp().getMaxHp())) {
                        targetHero = hero;
                    }
                }
            }

            retList.add(targetHero);
        } else if (targetType.equals(ESkillTargetType.EnemyLowestHp)) {
            BattleHero targetHero = null;
            List<BattleHero> heroes = filterDead(battleData.getEnemy(srcHero).getHeroes());
            for (BattleHero hero : heroes) {
                if (targetHero == null) {
                    targetHero = hero;
                } else {
                    if (hero.getHp() < targetHero.getHp()) {
                        targetHero = hero;
                    }
                }
            }

            retList.add(targetHero);
        } else if (targetType.equals(ESkillTargetType.Trigger)) {
            retList.add(battle.getCurActiveHero());
        }

        if (retList.size() == 0) {
            // 默认选择敌方第一个
            retList.add(battleData.getEnemy(srcHero).getFirst());
        }

        return retList;
    }

    private static List<BattleHero> filterDead(List<BattleHero> src) {
        List<BattleHero> ret = src.stream().filter((elem) -> {
            return !elem.isDead();
        }).collect(Collectors.toList());

        return ret;
    }

    // 随机出n个不同的英雄目标
    private static List<BattleHero> randHeroes(List<BattleHero> heroes, int randNum) {
        List<BattleHero> listRandom = new ArrayList<>();
        if (heroes.size() < randNum) {
            randNum = heroes.size();
        }

        List<Integer> indexList = new ArrayList<>();
        for (int i = 0; i < heroes.size(); i++) {
            indexList.add(i);
        }

        for (int i = randNum; i >= 1; i--) {
            Random random = new Random();
            Math.random();
            int j = random.nextInt(indexList.size());
            listRandom.add(heroes.get(indexList.get(j)));
            indexList.remove(j);
        }

        return listRandom;
    }
}
